package day32;

import java.util.Optional;

// Optional对象
// 可以理解为一种容器, 可以最大化避免空指针异常
// 常见用法: 作为方法的返回值类型
public class Demo05 {
	public static void main(String[] args) {
		test01();
	}

	private static void test01() {
		// 创建Optional对象

		// 创建一个没有值的op对象
		Optional<String> op = Optional.empty();

		// of()方法创建op对象
		Optional<String> op2 = Optional.of("aaaaa");
		// 该方式创建op对象时, 不支持null
		// Optional<String> op3 = Optional.of(null);

		// 创建op对象时, 允许为null
		Optional<String> op4 = Optional.ofNullable("aaa");
		Optional<String> op5 = Optional.ofNullable(null);

		// -------
		// 判断op对象及操作
		// 判断op对象是否有值
		System.out.println(op.isPresent());
		System.out.println(op2.isPresent());
		System.out.println(op4.isPresent());
		System.out.println(op5.isPresent());
		// 如果op对象有值, 操作它
		// if(op2.isPresent()) {}
		// ifPresent(Consumer), 相当于if为true然后进行操作
		// 具体的操作就是由Consumer的实现来完成
		// ifPresent()方法的参数lambda表达式的参数, 就是op对象的值
		op2.ifPresent(val -> System.out.println(val));

		// --------
		// 获取op对象的值
		// 对于空值的op对象, 直接get会报错NoSuchElementException
		// String str1 = op.get();

		// orElse(): 如果op对象有值, 则获取op的值
		// 如果op对象没有值, 则获取参数
		String str2 = op.orElse("abc");
		System.out.println(str2);

		String str3 = op2.orElse("111");
		System.out.println(str3);

		// orElseGet(), 提供一个供给型接口的实现
		// 如果op对象有值, 则获取op对象的值
		// 如果op对象没有值, 则获取lambda表达式的结果
		String str4 = op.orElseGet(() -> "default val");
		System.out.println(str4);
		
		// orElseThrow(),  提供一个供给型接口的实现
		// 如果op对象有值, 则获取op的值
		// 如果op对象没有值, 则获取lambda表达式的结果
		// 注意: 该方式提供的lambda表达式结果必须是Throwable体系成员
		// 也就是: 如果op有值则取值, 如果op没值则抛出指定异常
		String str5 = op.orElseThrow(NullPointerException::new);
	}
}
